#!/usr/bin/env python
# -*- coding: UTF-8 -*-

'''Implementation of http://en.wikipedia.org/wiki/Langton's_ant'''

from cellular_engine.engine import TileManager
from cellular_engine.constants import *

ROTATION_TO_DIRECTION = {0: DIR_NORTH,
                         90: DIR_EAST,
                         180: DIR_SOUTH,
                         270: DIR_WEST}


class BasicLangtonsAnt(object):
    def __init__(self, world_size, tile_size, world_type):
        self.black_cells = set()

        self.generation = 0

        self.manager = TileManager(world_size, tile_size, world_type)

        self.rotation = 270
        self.position = world_size[0] / 2, world_size[1] / 2

    def game_loop(self):
        if self.position in self.black_cells:
            self.rotation -= 90
            self.black_cells.remove(self.position)
            self.old_position = (self.position, False)

        else:
            self.rotation += 90
            self.black_cells.add(self.position)
            self.old_position = (self.position, True)

        if self.rotation == 360:
            self.rotation = 0
        elif self.rotation == -90:
            self.rotation = 270

        self.move()
        self.generation += 1

    def move(self):
        self.position = self.manager.get_pos_in_direction(self.position,
                                                          ROTATION_TO_DIRECTION[self.rotation])


class AdvancedLangtonsAnt(BasicLangtonsAnt):
    '''LangtonsAnt with cells that can have several states'''
    def __init__(self, world_size, tile_size, world_type, state_string='LR'):
        self.cells = {}

        self.generation = 0

        self.manager = TileManager(world_size, tile_size, world_type)

        self.rotation = 270
        self.position = world_size[0] / 2, world_size[1] / 2
        self.state_string = state_string

        self.max_states = len(state_string)

    def game_loop(self):
        position = self.position

        try:
            behavior = self.state_string[self.cells[position]]
        except KeyError:
            behavior = self.state_string[1]

        try:
            self.cells[position] += 1
        except KeyError:
            self.cells[position] = 0

        if self.cells[position] == self.max_states:
            self.cells[position] = 0

        self.old_position = (position, self.cells[position])

        if behavior == 'L':
            self.rotation -= 90
        else:
            self.rotation += 90

        if self.rotation == 360:
            self.rotation = 0
        elif self.rotation == -90:
            self.rotation = 270

        self.move()
        self.generation += 1
